package net.ib.mtalk.ui.buddy.contact;

import java.util.ArrayList;
import java.util.List;

import com.google.protobuf.micro.InvalidProtocolBufferMicroException;

import net.ib.mntalk.protocol.Common.BuddyInfo;
import net.ib.mtalk.R;
import net.ib.mtalk.base.BaseFragmentActivity;
import net.ib.mtalk.database.DatabaseContract.BuddyTable;
import net.ib.mtalk.database.DatabaseContract.ContactTable;
import net.ib.mtalk.database.helper.NotifyingAsyncQueryHandler;
import net.ib.mtalk.ui.buddy.item.BuddyActionItem;
import net.ib.mtalk.ui.buddy.item.BuddyActionItem.ItemType;
import net.ib.mtalk.ui.dialog.DialogListItem;
import net.ib.mtalk.ui.dialog.DialogMenuOnClickListener;
import net.ib.mtalk.ui.setting.SettingsActivity;
import net.ib.mtalk.ui.widget.QuickAction;
import net.ib.mtalk.util.MTalkLogWriter;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract.Contacts;
import android.speech.RecognizerIntent;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.support.v4.widget.CursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

public class BuddyContactListActivity extends BaseFragmentActivity implements OnClickListener, DialogMenuOnClickListener{
	private static Context mContext;
	
	public static final int SMS_SEND     = 1;
	public static final int SETTING   	 = 2;

	public static final int MODE_CONTACT = 1;
	
	private static boolean showcheckbox = false;
	private LinearLayout layout;
	private Button btn_groupChat;
	private Button btn_groupMessage;
	private Button btn_cancel;
	private static NotifyingAsyncQueryHandler queryHandler;
	public static EditText buddy_search;
	private ImageButton voice_btn;
	BuddyContactListFragment list;
	
	private static final int QUERY_CONTACT = 0;
	
	public static final int REQ_CONTACT_VOICE_RECOGNITION = 101;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_buddy_contact_list);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		
		mContext = this;
		
		FragmentManager fm = getSupportFragmentManager();
		
		if(savedInstanceState == null) {
			list = new BuddyContactListFragment();
			fm.beginTransaction().add(R.id.buddy_talk_list, list).commit();
		}
		
		layout = (LinearLayout)findViewById(R.id.bc_layout01);
		btn_groupChat = (Button) findViewById(R.id.btn_groupChat);
		btn_groupChat.setText(R.string.contact_sms_write);
		btn_groupChat.setOnClickListener(this);
		btn_groupMessage = (Button) findViewById(R.id.btn_groupMessage);
		btn_groupMessage.setVisibility(View.GONE);
		btn_cancel = (Button) findViewById(R.id.btn_cancel);
		btn_cancel.setOnClickListener(this);
		buddy_search = (EditText) findViewById(R.id.buddy_search);
		buddy_search.addTextChangedListener(watcher());
		// 보이스 검색
		voice_btn = (ImageButton) findViewById(R.id.buddy_voice_btn);
		voice_btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
				intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
				intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.buddy_voice_recognition));
				getParent().startActivityForResult(intent, REQ_CONTACT_VOICE_RECOGNITION);
			}
		});
	}
	
	private static TextWatcher watcher() {
		TextWatcher textWatcher = new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,	int after) {
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				BuddyContactListFragment.mContactsObserver.onChange(true);
			}
		};
		return textWatcher;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
			menu.clear();
//			menu.add(0, SMS_SEND, 0, R.string.contact_sms_send);
			menu.add(0, SETTING, 0, R.string.settings).setIcon(R.drawable.menu_icon_settings);
		return true;
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		if(item.getItemId() == SMS_SEND){
			showcheckbox = true;
			layout.setVisibility(View.VISIBLE);
			changeMode();
			
		} else if(item.getItemId() == SETTING){
			Intent intent = new Intent(this, SettingsActivity.class);
			startActivity(intent);
		}
		return super.onMenuItemSelected(featureId, item);
	}
	
	
	private void changeMode() {
		BuddyContactListFragment list = new BuddyContactListFragment();
		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		ft.replace(R.id.buddy_talk_list, list);
		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
	    ft.commit();
	}


	public static class BuddyContactListFragment extends ListFragment {

		private CursorAdapter mAdapter;
		private List<Long> checked_item = new ArrayList<Long>();
		long contactId = -1;
		private List<Long> list = new ArrayList<Long>();
		private List<Integer> arr_group = new ArrayList<Integer>();
		
		public final char HANGUL_BEGIN_UNICODE = 44032; // 가
		public final char HANGUL_END_UNICODE = 55203; // 힣
		public final static char HANGUL_BASE_UNIT = 588;//각자음 마다 가지는 글자수
		public final char[] INITIAL_SOUND = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ',
	        'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' };
		
		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);
			setHasOptionsMenu(true);
			
			/*String sortOrder = Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
			String [] PROJECTION = {
					Contacts._ID,
					Contacts.DISPLAY_NAME,
					Contacts.PHOTO_ID
			};
			Cursor c = getActivity().getApplicationContext().getContentResolver().query(Contacts.CONTENT_URI, PROJECTION, 
					null, null, sortOrder);*/
			list = getBuddyList(getActivity());
			mAdapter = new BuddyContactAdapter(getActivity(), null, 0, showcheckbox, list, checked_item, arr_group);
			ListView listView = getListView();
			listView.setDivider(getResources().getDrawable(R.drawable.inbox_divider));
			listView.setDividerHeight(1);
			listView.setFastScrollEnabled(true);
			listView.setScrollingCacheEnabled(false);
			listView.setAdapter(mAdapter);
//			setListAdapter(mAdapter);
			queryHandler = new NotifyingAsyncQueryHandler(getActivity().getParent().getContentResolver(), onQueryReturn);
			
			String [] PROJECTION = {
					Contacts._ID,
					Contacts.DISPLAY_NAME
			};
			String selection = "(" + Contacts.DISPLAY_NAME + " NOTNULL AND " + Contacts.IN_VISIBLE_GROUP + " ='1' AND " + 
				Contacts.HAS_PHONE_NUMBER + "='1' AND " + Contacts.DISPLAY_NAME + " LIKE ?" + ")";
			String[] selectionArgs = {"%" + buddy_search.getText().toString() + "%"};
			String sortOrder = "case"+
			  " when substr("+Contacts.DISPLAY_NAME+", 1, 1) BETWEEN 'ㄱ' AND '힣'  then 1 "+
			  " when substr("+Contacts.DISPLAY_NAME+", 1, 1) BETWEEN 'A' AND 'Z' then 2 "+  
			  " when substr("+Contacts.DISPLAY_NAME+", 1, 1) BETWEEN 'a' AND 'z' then 3 "+           
			  " else 4 end, "+Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";  //ASC로 하면 ㄱ,ㄴ초성으로 되어 있는 한글이 먼저 정렬됨
			queryHandler.startQuery(QUERY_CONTACT, null, Contacts.CONTENT_URI, PROJECTION, selection, selectionArgs, sortOrder);
		}
		
		/**
		 * 현재 Buddy 변화 상태를 Observing 한다. 
		 */
		static ContentObserver mContactsObserver = new ContentObserver(new Handler()) {
			public void onChange(boolean selfChange) {
				String [] PROJECTION = {
						Contacts._ID,
						Contacts.DISPLAY_NAME
				};
				String selection = "(" + Contacts.DISPLAY_NAME + " NOTNULL AND " + Contacts.IN_VISIBLE_GROUP + " ='1' AND " + Contacts.HAS_PHONE_NUMBER + "='1')";
				String sortOrder = "case"+
				  " when substr("+Contacts.DISPLAY_NAME+", 1, 1) BETWEEN 'ㄱ' AND '힣'  then 1 "+
				  " when substr("+Contacts.DISPLAY_NAME+", 1, 1) BETWEEN 'A' AND 'Z' then 2 "+  
				  " when substr("+Contacts.DISPLAY_NAME+", 1, 1) BETWEEN 'a' AND 'z' then 3 "+           
				  " else 4 end, "+Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";  //ASC로 하면 ㄱ,ㄴ초성으로 되어 있는 한글이 먼저 정렬됨
				if(buddy_search.getText() == null || buddy_search.getText().toString().equals("")){
					queryHandler.startQuery(QUERY_CONTACT, null, Contacts.CONTENT_URI, PROJECTION, selection, null, sortOrder);
				} else{
					queryHandler.startQuery(QUERY_CONTACT, null, Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(buddy_search.getText().toString())), PROJECTION, selection, null, sortOrder);
				}
			};
		};
		
		private void makeNameTag(Cursor data) {
			
			ArrayList<Character> char_group = new ArrayList<Character>();
			arr_group.clear();
//			Cursor cursor = mContext.getContentResolver().query(Contacts.CONTENT_URI, null, 
//					"(" + Contacts.DISPLAY_NAME + " NOTNULL AND " + Contacts.IN_VISIBLE_GROUP + " =1)", null, null);
//			cursor.close();
//			data.moveToPosition(data.getCount());
			data.moveToFirst();
			data.moveToPrevious();
			while(data.moveToNext()){	// 0번째부터 다시 NameTag 생성
				 /** 초성을 판별하여 인덱스 생성*/
		        String a = data.getString(data.getColumnIndexOrThrow(Contacts.DISPLAY_NAME));
		        if(a == null || "".equals(a)){
		        	a = " ";
		        }
		        char b = a.charAt(0);
		        char d;
		        if(b < HANGUL_BEGIN_UNICODE){
		        	d = b;
		        } else{
		        	d = INITIAL_SOUND[(b-HANGUL_BEGIN_UNICODE)/HANGUL_BASE_UNIT];
		        }
		        
		        if(!char_group.contains(d)) {
		        	char_group.add(d);
		        	if(!arr_group.contains(data.getPosition())) arr_group.add(data.getPosition());
		        }
			}
		}
		
		NotifyingAsyncQueryHandler.AsyncQueryListener onQueryReturn = new NotifyingAsyncQueryHandler.AsyncQueryListener() {
			@Override
			public void onQueryComplete(int token, Object cookie, Cursor cursor) {
				switch (token){
				case QUERY_CONTACT:
					getActivity().getParent().getParent().startManagingCursor(cursor);
					mAdapter.changeCursor(cursor);
					makeNameTag(cursor);
					break;
				}
			}
			
			@Override
			public void onUpdateComplete(int token, Object cookie, int result) {
			}
			
			@Override
			public void onInsertComplete(int token, Object cookie, Uri uri) {
			}
			
			@Override
			public void onDeleteComplete(int token, Object cookie, int result) {
			}
		};
		
		private List<Long> getBuddyList(Context context) {
			List<Long> buddyList = new ArrayList<Long>();
			
			String selection = ContactTable.KEY_BUDDY_UUID_MSB + " NOT NULL";
			Cursor cursor = context.getContentResolver().query(ContactTable.CONTENT_URI, new String[]{ContactTable.KEY_CONTACT_PHONE_ID}, selection, null, null);
			try{
				while(cursor.moveToNext()){
					buddyList.add(cursor.getLong(cursor.getColumnIndexOrThrow(ContactTable.KEY_CONTACT_PHONE_ID)));
				}
			} finally{
				cursor.close();
			}
			return buddyList;
		}

		@Override
		public void onResume() {
			super.onResume();
			buddy_search.addTextChangedListener(watcher());
			getActivity().getParent().getContentResolver().registerContentObserver(Contacts.CONTENT_FILTER_URI, true, mContactsObserver);
			mContactsObserver.onChange(true);
		}
		
		@Override
		public void onPause() {
			super.onPause();
			buddy_search.removeTextChangedListener(watcher());
			getActivity().getParent().getContentResolver().unregisterContentObserver(mContactsObserver);
		}
		
		@Override
		public void onListItemClick(ListView l, View v, int position, long id) {
			super.onListItemClick(l, v, position, id);
			Cursor cursor = (Cursor) l.getItemAtPosition(position);
			long contacts_id = cursor.getLong(cursor.getColumnIndex(Contacts._ID));
//			Toast.makeText(mContext, contacts_id+"", Toast.LENGTH_SHORT).show();
			if(list.contains(contacts_id)){	// 엠앤톡 사용자
				String selection = ContactTable.KEY_CONTACT_PHONE_ID + "=?";
				String[] selectionArgs = {String.valueOf(contacts_id)};
				Cursor cursor2 = mContext.getContentResolver().query(ContactTable.buildContactBuddy(), null, selection, selectionArgs, null);
				try{
					BuddyInfo buddyInfo = null;
					int buddy_id = 0;
					int favorite = 0;
					long msb = 0;
					long lsb = 0;
					if(cursor2.moveToFirst()){
						buddy_id = cursor2.getInt(cursor2.getColumnIndexOrThrow(BuddyTable._ID));
						buddyInfo = BuddyInfo.parseFrom(cursor2.getBlob(cursor2.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_INFO)));
						favorite = cursor2.getInt(cursor2.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_FAVORITE));
						msb = cursor2.getLong(cursor2.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_UUID_MSB));
						lsb = cursor2.getLong(cursor2.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_UUID_LSB));
					}
					goQuickAction(v, buddy_id, msb, lsb, buddyInfo.getName().getDisplayName(), buddyInfo, Integer.valueOf(String.valueOf(contacts_id)), favorite, null, getActivity().getParent());
				} catch (InvalidProtocolBufferMicroException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} finally{
					cursor2.close();
				}
			} else {	// 엠앤톡 미사용자
				String selection = ContactTable.KEY_CONTACT_PHONE_ID + "=?";
				String[] selectionArgs = {String.valueOf(contacts_id)};
				Cursor cursor2 = mContext.getContentResolver().query(ContactTable.CONTENT_URI, null, selection, selectionArgs, null);
				try{
					goQuickAction(v, -1, 0, 0, null, null, Integer.valueOf(String.valueOf(contacts_id)), 0, null, getActivity().getParent());
				} finally{
					cursor2.close();
				}
			}
		}
	}
	
	public static void goQuickAction(View v, int buddy_id, long receiverMsb, long receiverLsb, String displayName, BuddyInfo buddyInfo, int raw_id, int favorite, String number, Activity activity) {
		try {
			// 액션 바를 띄워준다.
			QuickAction quickAction = new QuickAction(v.findViewById(R.id.buddy_child_profile));
			if(buddy_id != -1){
				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.ONE_TO_ONE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
				if(raw_id != -1){
					quickAction.addActionItem(new BuddyActionItem(activity, ItemType.SEND_MESSAGE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, MODE_CONTACT, quickAction));
					quickAction.addActionItem(new BuddyActionItem(activity, ItemType.CALL, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, MODE_CONTACT, quickAction));
				}
				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.PROFILEVIEW, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.FAVORITE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
			} else{
				quickAction.addActionItem(new BuddyActionItem(activity, ItemType.SEND_MESSAGE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, MODE_CONTACT, quickAction));
				quickAction.addActionItem(new BuddyActionItem(activity, ItemType.INVITE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, MODE_CONTACT, quickAction));
				quickAction.addActionItem(new BuddyActionItem(activity, ItemType.CALL, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, MODE_CONTACT, quickAction));
				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.PHONECONTACT, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
			}
			quickAction.setAnimStyle(QuickAction.ANIM_AUTO);
			quickAction.setMode(QuickAction.MODE_DIALOG);
			quickAction.show();
		} catch (IllegalArgumentException e) {
			MTalkLogWriter.e(e);
		}
	}

	@Override
	public void onClick(View v) {
		if(v.getId() == R.id.btn_groupChat){	// SMS 작성
			Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + "01190732770"));
			startActivity(intent);
		} else if(v.getId() == R.id.btn_cancel){	// 선택 취소
			
		} 
	}
	
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		if(showcheckbox == true && keyCode == KeyEvent.KEYCODE_BACK){
			showcheckbox = false;
			layout.setVisibility(View.GONE);
			changeMode();
			
			return true;
		}
		return super.onKeyUp(keyCode, event);
	}

	@Override
	public boolean onClickDailogMenu(Object obj, int tag) {
		DialogListItem item = (DialogListItem) obj;
		return false;
	}

	
	/*public Bitmap getPhoto(ContentResolver contentResolver, Long contactId){
		Uri contactPhotoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
		
		InputStream photoDataStream = Contacts.openContactPhotoInputStream(contentResolver, contactPhotoUri);
		Bitmap  photo = BitmapFactory.decodeStream(photoDataStream);
		
		return photo;
	}
	
	class ContactAccessor {
		public ContactsItem loadContact (ContentResolver contentResolver, Uri contactUri){
			ContactsItem contactsItem = new ContactsItem();
			
			Cursor cursor = contentResolver.query(contactUri, new String[] {Contacts._ID, Contacts.DISPLAY_NAME, Phone.NUMBER},
					null, null, Contacts.DISPLAY_NAME);
			 try {
				if(cursor.moveToFirst()){
					contactsItem.setId(cursor.getLong(cursor.getColumnIndex(Contacts._ID)));
					contactsItem.setDisplayName(cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)));
					contactsItem.setPhoneNumber(cursor.getString(cursor.getColumnIndex(Phone.NUMBER)));
//					contactsItem.setPhotoUri(photoUri)
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
			return contactsItem;
		}
	}*/
}
